package com.engine.salary.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.api.formmode.mybatis.util.SqlProxyHandle;
import com.engine.common.util.ServiceUtil;
import com.engine.core.impl.Service;
import com.engine.hrmelog.entity.dto.LoggerContext;
import com.engine.salary.config.SalaryElogConfig;
import com.engine.salary.entity.datacollection.DataCollectionEmployee;
import com.engine.salary.entity.salaryacct.bo.SalaryAcctConfig;
import com.engine.salary.entity.salaryacct.bo.SalaryAcctEmployeeBO;
import com.engine.salary.entity.salaryacct.dto.SalaryAcctEmployeeCountDTO;
import com.engine.salary.entity.salaryacct.param.*;
import com.engine.salary.entity.salaryacct.po.SalaryAcctEmployeePO;
import com.engine.salary.entity.salaryacct.po.SalaryAcctRecordPO;
import com.engine.salary.entity.salaryarchive.dto.SalaryArchiveDataDTO;
import com.engine.salary.entity.salarysob.dto.SalarySobCycleDTO;
import com.engine.salary.entity.salarysob.po.SalarySobItemPO;
import com.engine.salary.entity.salarysob.param.SalarySobQueryParam;
import com.engine.salary.entity.salarysob.po.SalarySobPO;
import com.engine.salary.entity.taxagent.param.TaxAgentQueryParam;
import com.engine.salary.entity.taxagent.po.TaxAgentPO;
import com.engine.salary.enums.OperateTypeEnum;
import com.engine.salary.enums.auth.AuthFilterTypeEnum;
import com.engine.salary.enums.salaryaccounting.LockStatusEnum;
import com.engine.salary.enums.salaryaccounting.SalaryAcctRecordStatusEnum;
import com.engine.salary.exception.SalaryRunTimeException;
import com.engine.salary.mapper.salaryacct.SalaryAcctEmployeeMapper;
import com.engine.salary.mapper.salarysob.SobTaxLinkMapper;
import com.engine.salary.mapper.sys.SalarySysConfMapper;
import com.engine.salary.report.entity.param.SalaryStatisticsReportDataQueryParam;
import com.engine.salary.service.*;
import com.engine.salary.sys.constant.SalarySysConstant;
import com.engine.salary.service.auth.AuthService;
import com.engine.salary.service.auth.AuthServiceImpl;
import com.engine.salary.sys.constant.SalarySysConstant;
import com.engine.salary.sys.entity.vo.OrderRuleVO;
import com.engine.salary.sys.service.SalarySysConfService;
import com.engine.salary.sys.service.impl.SalarySysConfServiceImpl;
import com.engine.salary.util.SalaryDateUtil;
import com.engine.salary.util.SalaryEntityUtil;
import com.engine.salary.util.SalaryI18nUtil;
import com.engine.salary.util.db.MapperProxyFactory;
import com.engine.salary.util.page.PageInfo;
import com.engine.salary.util.page.SalaryPageUtil;
import com.engine.salary.util.valid.ValidUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import weaver.hrm.User;

import java.util.*;
import java.util.stream.Collectors;

import static com.engine.salary.sys.constant.SalarySysConstant.REPORT_ORGANIZATIN_TYPE;

/**
 * 薪资核算人员
 * <p>Copyright: Copyright (c) 2022</p>
 * <p>Company: 泛微软件</p>
 *
 * @author qiantao
 * @version 1.0
 **/
@Slf4j
public class SalaryAcctEmployeeServiceImpl extends Service implements SalaryAcctEmployeeService {

    private SalaryAcctEmployeeMapper getSalaryAcctEmployeeMapper() {
        return MapperProxyFactory.getProxy(SalaryAcctEmployeeMapper.class);
    }

    private SobTaxLinkMapper getSobTaxLinkMapper() {
        return MapperProxyFactory.getProxy(SobTaxLinkMapper.class);
    }

    private SalaryAcctRecordService getSalaryAcctRecordService(User user) {
        return ServiceUtil.getService(SalaryAcctRecordServiceImpl.class, user);
    }

    private SalaryAcctResultService getSalaryAcctResultService(User user) {
        return ServiceUtil.getService(SalaryAcctResultServiceImpl.class, user);
    }

    private SalaryAcctReportServiceImpl getSalaryAcctReportService(User user) {
        return ServiceUtil.getService(SalaryAcctReportServiceImpl.class, user);
    }

    public AuthService getAuthService(User user) {
        return ServiceUtil.getService(AuthServiceImpl.class, user);
    }

//    private SalaryCheckResultDetailService salaryCheckResultDetailService;

//    private SalaryComparisonResultService salaryComparisonResultService;

    private SalarySobService getSalarySobService(User user) {
        return ServiceUtil.getService(SalarySobServiceImpl.class, user);
    }

    private SalaryEmployeeService getSalaryEmployeeService(User user) {
        return ServiceUtil.getService(SalaryEmployeeServiceImpl.class, user);
    }

    private SalaryArchiveService getSalaryArchiveService(User user) {
        return ServiceUtil.getService(SalaryArchiveServiceImpl.class, user);
    }

    private TaxAgentService getTaxAgentService(User user) {
        return ServiceUtil.getService(TaxAgentServiceImpl.class, user);
    }

    private SalarySysConfMapper getSalarySysConfMapper() {
        return SqlProxyHandle.getProxy(SalarySysConfMapper.class);
    }

    private SalarySysConfService getSalarySysConfService(User user) {
        return ServiceUtil.getService(SalarySysConfServiceImpl.class, user);
    }

    private SalaryCacheService getSalaryCacheService(User user) {
        return ServiceUtil.getService(SalaryCacheServiceImpl.class, user);
    }

    private SalaryAcctSobConfigService getSalaryAcctSobConfigService(User user) {
        return ServiceUtil.getService(SalaryAcctSobConfigServiceImpl.class, user);
    }


    private boolean isRealOrg = "1".equals(getSalaryCacheService(user).get(REPORT_ORGANIZATIN_TYPE));

    @Override
    public List<SalaryAcctEmployeeCountDTO> countBySalaryAcctRecordId(Collection<Long> salaryAcctRecordIds) {
        if (CollectionUtils.isEmpty(salaryAcctRecordIds)) {
            return Collections.emptyList();
        }
        return getSalaryAcctEmployeeMapper().countGroupBySalaryAcctRecordId(salaryAcctRecordIds);
    }

    @Override
    public SalaryAcctEmployeePO getById(Long id) {
        SalaryAcctEmployeePO po = getSalaryAcctEmployeeMapper().getById(id);
        SalaryI18nUtil.i18n(po);
        return po;
    }

    @Override
    public List<SalaryAcctEmployeePO> listByIds(Collection<Long> ids) {
        return getSalaryAcctEmployeeMapper().listSome(SalaryAcctEmployeePO.builder().ids(ids).build());
    }

    @Override
    public List<SalaryAcctEmployeePO> listBySalaryAcctRecordId(Long salaryAcctRecordId) {
        return getSalaryAcctEmployeeMapper().listSome(SalaryAcctEmployeePO.builder().salaryAcctRecordId(salaryAcctRecordId).build());
    }

    @Override
    public List<SalaryAcctEmployeePO> listBySalaryAcctRecordIds(Collection<Long> salaryAcctRecordIds) {
        return getSalaryAcctEmployeeMapper().listSome(SalaryAcctEmployeePO.builder().salaryAcctRecordIds(salaryAcctRecordIds).build());
    }

    @Override
    public List<SalaryAcctEmployeePO> listBySalaryAcctRecordIdAndTaxAgentId(Long salaryAcctRecordId, Long taxAgentId) {
        return getSalaryAcctEmployeeMapper().listSome(SalaryAcctEmployeePO.builder().salaryAcctRecordId(salaryAcctRecordId).taxAgentId(taxAgentId).build());
    }

    @Override
    public void addFromReduce(SalaryAcctEmployeeAddParam addParam) {
//        ValidUtil.doValidator(addParam);
//        // 查询薪资核算记录
//        SalaryAcctRecordPO salaryAcctRecordPO = getSalaryAcctRecordService(user).getById(addParam.getSalaryAcctRecordId());
//        if (Objects.isNull(salaryAcctRecordPO)) {
//            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98747, "薪资核算记录不存在或已被删除"));
//        }
//        // 查询环比减少的薪资核算人员
//        List<SalaryAcctEmployeePO> salaryAcctEmployeePOS = listByIds(addParam.getIds());
//        if (CollectionUtils.isEmpty(salaryAcctEmployeePOS)) {
//            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98830, "薪资核算人员不存在或已被删除"));
//        }
//        // 添加薪资核算人员
//        Date now = new Date();
//        List<SalaryAcctEmployeePO> newSalaryAcctEmployeePOS = salaryAcctEmployeePOS.stream().map(salaryAcctEmployeePO -> new SalaryAcctEmployeePO()
//                .setSalaryAcctRecordId(salaryAcctRecordPO.getId()).setSalarySobId(salaryAcctRecordPO.getSalarySobId()).setSalaryMonth(salaryAcctRecordPO.getSalaryMonth()).setEmployeeId(salaryAcctEmployeePO.getEmployeeId()).setTaxAgentId(salaryAcctEmployeePO.getTaxAgentId()).setTenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY).setCreateTime(now).setUpdateTime(now).setCreator((long) user.getUID()).setDeleteType(0)).collect(Collectors.toList());
//        if (CollectionUtils.isNotEmpty(newSalaryAcctEmployeePOS)) {
//            batchSave(newSalaryAcctEmployeePOS);
//        }
    }

    @Override
    public List<SalaryAcctEmployeePO> listBySalaryAcctRecordIdAndIds(Long salaryAcctRecordId, Collection<Long> ids) {
        return getSalaryAcctEmployeeMapper().listSome(SalaryAcctEmployeePO.builder().salaryAcctRecordId(salaryAcctRecordId).ids(ids).build());
    }

    @Override
    public List<SalaryAcctEmployeePO> listBySalaryAcctRecordIdAndEmployeeIds(Long salaryAcctRecordId, Collection<Long> employeeIds) {
        if (CollectionUtils.isEmpty(employeeIds)) {
            return Collections.emptyList();
        }
        return getSalaryAcctEmployeeMapper().listSome(SalaryAcctEmployeePO.builder().salaryAcctRecordId(salaryAcctRecordId).employeeIds(employeeIds).build());
    }

    @Override
    public List<SalaryAcctEmployeePO> listBySalaryAcctRecordIdsAndEmployeeIds(Collection<Long> salaryAcctRecordIds, Collection<Long> employeeIds) {
        if (CollectionUtils.isEmpty(salaryAcctRecordIds) || CollectionUtils.isEmpty(employeeIds)) {
            return Collections.emptyList();
        }
        List<List<Long>> partition = Lists.partition((List<Long>) employeeIds, 500);
        List<SalaryAcctEmployeePO> list = new ArrayList<>();
        partition.forEach(l -> {
            list.addAll(getSalaryAcctEmployeeMapper().listSome(SalaryAcctEmployeePO.builder().salaryAcctRecordIds(salaryAcctRecordIds).employeeIds(l).build()));
        });

        return list;
    }

    @Override
    public List<SalaryAcctEmployeePO> listByRecordIdsAndEmpIdAndTaxAgentId(Collection<Long> salaryAcctRecordIds, Long employeeId, Long taxAgentId) {
        if (CollectionUtils.isEmpty(salaryAcctRecordIds)) {
            return Collections.emptyList();
        }
        return getSalaryAcctEmployeeMapper().listSome(SalaryAcctEmployeePO.builder().salaryAcctRecordIds(salaryAcctRecordIds).employeeId(employeeId).taxAgentId(taxAgentId).build());
    }

    @Override
    public PageInfo<SalaryAcctEmployeePO> listPageByParam(SalaryAcctEmployeeQueryParam queryParam) {
        ValidUtil.doValidator(queryParam);

        //排序配置
        OrderRuleVO orderRule = getSalarySysConfService(user).orderRule();
        queryParam.setOrderRule(orderRule);

        // 分页参数
        // 查询薪资核算人员
        List<SalaryAcctEmployeePO> salaryAcctEmployeePOS = getSalaryAcctEmployeeMapper().listPage(queryParam);
        return SalaryPageUtil.buildPage(queryParam.getCurrent(), queryParam.getPageSize(),
                salaryAcctEmployeePOS, SalaryAcctEmployeePO.class);
    }

    @Override
    public List<SalaryAcctEmployeePO> listByParam(SalaryAcctEmployeeQueryParam queryParam) {
//        ValidUtil.doValidator(queryParam);
        //排序配置
        OrderRuleVO orderRule = getSalarySysConfService(user).orderRule();
        queryParam.setOrderRule(orderRule);
        return getSalaryAcctEmployeeMapper().list(queryParam);
    }

    @Override
    public PageInfo<SalaryAcctEmployeePO> listPageByResultQueryParam(SalaryAcctResultQueryParam queryParam) {
        ValidUtil.doValidator(queryParam);
        // 薪资核算人员的查询参数
        SalaryAcctEmployeeQueryParam salaryAcctEmployeeQueryParam = new SalaryAcctEmployeeQueryParam();
        BeanUtils.copyProperties(queryParam, salaryAcctEmployeeQueryParam);
        // 查询薪资核算人员（分页）
        // 如果需要筛选是否合并计税
        if (StringUtils.isNotEmpty(queryParam.getConsolidatedTaxation()) && queryParam.getConsolidatedTaxation().equals("1")) {
            return listPageByParam4ConsolidatedTax(salaryAcctEmployeeQueryParam);
        } else {
            return listPageByParam(salaryAcctEmployeeQueryParam);
        }
    }

    @Override
    public List<SalaryAcctEmployeePO> listByResultQueryParam(SalaryAcctResultQueryParam queryParam) {
        // 薪资核算人员的查询参数
        SalaryAcctEmployeeQueryParam salaryAcctEmployeeQueryParam = new SalaryAcctEmployeeQueryParam();
        BeanUtils.copyProperties(queryParam, salaryAcctEmployeeQueryParam);
        // 查询薪资核算人员
        List<SalaryAcctEmployeePO> salaryAcctEmployeePOS;
        // 如果需要筛选是否合并计税
        if (StringUtils.isNotEmpty(queryParam.getConsolidatedTaxation())) {
            salaryAcctEmployeePOS = listByParam4ConsolidatedTax(salaryAcctEmployeeQueryParam);
        } else {
            salaryAcctEmployeePOS = listByParam(salaryAcctEmployeeQueryParam);
        }
        return salaryAcctEmployeePOS;
    }


    @Override
    public PageInfo<SalaryAcctEmployeePO> listPageByParam4Reduce(SalaryAcctEmployeeQueryParam queryParam) {

        // 查询薪资核算人员
        List<SalaryAcctEmployeePO> salaryAcctEmployeePOS = listByParam4Reduce(queryParam);
        PageInfo<SalaryAcctEmployeePO> salaryAcctEmployeePOPageInfo = SalaryPageUtil.buildPage(queryParam.getCurrent(), queryParam.getPageSize(), SalaryAcctEmployeePO.class);
        // 分页参数
        salaryAcctEmployeePOPageInfo.setTotal(salaryAcctEmployeePOS.size());
        salaryAcctEmployeePOPageInfo.setList(SalaryPageUtil.subList(queryParam.getCurrent(), queryParam.getPageSize(), salaryAcctEmployeePOS));
        return salaryAcctEmployeePOPageInfo;
    }

    @Override
    public PageInfo<SalaryAcctEmployeePO> listPageByParam4Add(SalaryAcctEmployeeQueryParam queryParam) {
        // 查询薪资核算人员
        List<SalaryAcctEmployeePO> salaryAcctEmployeePOS = listByParam4Add(queryParam);
        PageInfo<SalaryAcctEmployeePO> salaryAcctEmployeePOPageInfo = SalaryPageUtil.buildPage(queryParam.getCurrent(), queryParam.getPageSize(), SalaryAcctEmployeePO.class);
        // 分页参数
        salaryAcctEmployeePOPageInfo.setTotal(salaryAcctEmployeePOS.size());
        salaryAcctEmployeePOPageInfo.setList(SalaryPageUtil.subList(queryParam.getCurrent(), queryParam.getPageSize(), salaryAcctEmployeePOS));
        return salaryAcctEmployeePOPageInfo;
    }


    @Override
    public List<SalaryAcctEmployeePO> listByParam4Reduce(SalaryAcctEmployeeQueryParam queryParam) {
        // 查询上个月的薪资核算记录（同一个薪资账套）
        List<SalaryAcctRecordPO> salaryAcctRecordPOS = getSalaryAcctRecordService(user).listById4LastSalaryMonth(queryParam.getSalaryAcctRecordId());
        if (CollectionUtils.isEmpty(salaryAcctRecordPOS)) {
            return Collections.emptyList();
        }
        Set<Long> lastMonthSalaryAcctRecordIds = SalaryEntityUtil.properties(salaryAcctRecordPOS, SalaryAcctRecordPO::getId);
        // 本月的核算人员
        List<SalaryAcctEmployeePO> salaryAcctEmployeePOS = listBySalaryAcctRecordId(queryParam.getSalaryAcctRecordId());
        Set<String> keySet = SalaryEntityUtil.properties(salaryAcctEmployeePOS, salaryAcctEmployeePO -> salaryAcctEmployeePO.getEmployeeId() + "-" + salaryAcctEmployeePO.getTaxAgentId());
        // 上个月的核算人员
        queryParam.setSalaryAcctRecordId(null);
        queryParam.setSalaryAcctRecordIds(lastMonthSalaryAcctRecordIds);
        List<SalaryAcctEmployeePO> lastMonthSalaryAcctEmployeePOS = listByParam(queryParam);
        Map<String, SalaryAcctEmployeePO> lastMonthSalaryAcctEmployeePOMap = SalaryEntityUtil.convert2Map(lastMonthSalaryAcctEmployeePOS, salaryAcctEmployeePO -> salaryAcctEmployeePO.getEmployeeId() + "-" + salaryAcctEmployeePO.getTaxAgentId());

        List<SalaryAcctEmployeePO> resultList = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(keySet)) {
            lastMonthSalaryAcctEmployeePOMap.forEach((k, v) -> {
                if (!keySet.contains(k)) {
                    resultList.add(v);
                }
            });
        }
        return resultList;
    }

    @Override
    public List<SalaryAcctEmployeePO> listByParam4Add(SalaryAcctEmployeeQueryParam queryParam) {
        // 查询上个月的薪资核算记录（同一个薪资账套）
        List<SalaryAcctRecordPO> salaryAcctRecordPOS = getSalaryAcctRecordService(user).listById4LastSalaryMonth(queryParam.getSalaryAcctRecordId());
        if (CollectionUtils.isEmpty(salaryAcctRecordPOS)) {
            return Collections.emptyList();
        }
        Set<Long> lastMonthSalaryAcctRecordIds = SalaryEntityUtil.properties(salaryAcctRecordPOS, SalaryAcctRecordPO::getId);
        // 上个月的核算人员
        List<SalaryAcctEmployeePO> lastMonthSalaryAcctEmployeePOS = listBySalaryAcctRecordIds(lastMonthSalaryAcctRecordIds);
        Map<String, SalaryAcctEmployeePO> lastMonthSalaryAcctEmployeePOMap = SalaryEntityUtil.convert2Map(lastMonthSalaryAcctEmployeePOS, salaryAcctEmployeePO -> salaryAcctEmployeePO.getEmployeeId() + "-" + salaryAcctEmployeePO.getTaxAgentId());
        // 本月的核算人员
        List<SalaryAcctEmployeePO> salaryAcctEmployeePOS = listByParam(queryParam);
//        Set<String> keySet = SalaryEntityUtil.properties(salaryAcctEmployeePOS, salaryAcctEmployeePO -> salaryAcctEmployeePO.getEmployeeId() + "-" + salaryAcctEmployeePO.getTaxAgentId());
        Map<String, SalaryAcctEmployeePO> thisMonthSalaryAcctEmployeePOMap = SalaryEntityUtil.convert2Map(salaryAcctEmployeePOS, salaryAcctEmployeePO -> salaryAcctEmployeePO.getEmployeeId() + "-" + salaryAcctEmployeePO.getTaxAgentId());
        List<SalaryAcctEmployeePO> resultList = Lists.newArrayList();
        thisMonthSalaryAcctEmployeePOMap.forEach((k, v) -> {
            if (!lastMonthSalaryAcctEmployeePOMap.containsKey(k)) {
                resultList.add(v);
            }
        });
        return resultList;
    }


    @Override
    public PageInfo<SalaryAcctEmployeePO> listPageByParam4ConsolidatedTax(SalaryAcctEmployeeQueryParam queryParam) {
        //排序配置
        OrderRuleVO orderRule = getSalarySysConfService(user).orderRule();
        queryParam.setOrderRule(orderRule);
        // 查询合并计税的其他薪资核算记录
        List<SalaryAcctRecordPO> otherSalaryAcctRecordPOS = getSalaryAcctRecordService(user).listById4OtherConsolidatedTax(queryParam.getSalaryAcctRecordId());
        if (CollectionUtils.isEmpty(otherSalaryAcctRecordPOS)) {
            return new PageInfo<>();
        }
        // 查询合并计税的薪资核算人员
        Set<Long> otherSalaryAcctRecordIds = SalaryEntityUtil.properties(otherSalaryAcctRecordPOS, SalaryAcctRecordPO::getId);
        // 分页参数
        List<SalaryAcctEmployeePO> salaryAcctEmployeePOS = new ArrayList<>();
        if (CollUtil.isNotEmpty(queryParam.getIds())) {
            List<SalaryAcctEmployeePO> list = new ArrayList<>();
            List<List<Long>> partition = Lists.partition(queryParam.getIds(), 500);
            partition.forEach(ids -> {
                queryParam.setIds(ids);
                list.addAll(getSalaryAcctEmployeeMapper().list4ConsolidatedTax(otherSalaryAcctRecordIds, queryParam));
            });
            salaryAcctEmployeePOS = list;
        } else {
            salaryAcctEmployeePOS = getSalaryAcctEmployeeMapper().listPage4ConsolidatedTax(otherSalaryAcctRecordIds, queryParam);
        }
        return SalaryPageUtil.buildPage(queryParam.getCurrent(), queryParam.getPageSize(),
                salaryAcctEmployeePOS, SalaryAcctEmployeePO.class);
    }

    @Override
    public List<SalaryAcctEmployeePO> listByParam4ConsolidatedTax(SalaryAcctEmployeeQueryParam queryParam) {
        //排序配置
        OrderRuleVO orderRule = getSalarySysConfService(user).orderRule();
        queryParam.setOrderRule(orderRule);
        // 查询合并计税的其他薪资核算记录
        List<SalaryAcctRecordPO> otherSalaryAcctRecordPOS = getSalaryAcctRecordService(user).listById4OtherConsolidatedTax(queryParam.getSalaryAcctRecordId());
        if (CollectionUtils.isEmpty(otherSalaryAcctRecordPOS)) {
            return Collections.emptyList();
        }
        // 查询合并计税的薪资核算人员
        Set<Long> otherSalaryAcctRecordIds = SalaryEntityUtil.properties(otherSalaryAcctRecordPOS, SalaryAcctRecordPO::getId);

        List<SalaryAcctEmployeePO> list = new ArrayList<>();
        if (CollUtil.isNotEmpty(queryParam.getIds())) {
            List<List<Long>> partition = Lists.partition(queryParam.getIds(), 500);
            partition.forEach(ids -> {
                queryParam.setIds(ids);
                list.addAll(getSalaryAcctEmployeeMapper().list4ConsolidatedTax(otherSalaryAcctRecordIds, queryParam));
            });
            return list;
        }

        return getSalaryAcctEmployeeMapper().list4ConsolidatedTax(otherSalaryAcctRecordIds, queryParam);
    }

    @Override
    public void save(SalaryAcctEmployeeSaveParam saveParam) {
        ValidUtil.doValidator(saveParam);

        // 查询薪资核算记录
        SalaryAcctRecordPO salaryAcctRecordPO = getSalaryAcctRecordService(user).getById(saveParam.getSalaryAcctRecordId());
        if (Objects.isNull(salaryAcctRecordPO)) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98747, "薪资核算记录不存在或已被删除"));
        }
        // 查询薪资核算人员
        List<SalaryAcctEmployeePO> existSalaryAcctEmployeePOS = listBySalaryAcctRecordIdAndEmployeeIds(saveParam.getSalaryAcctRecordId(), saveParam.getEmployeeIds());
        if (CollectionUtils.isNotEmpty(existSalaryAcctEmployeePOS)) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(101581, "人员已存在，请勿重复添加"));
        }
        // 根据薪资账套查询薪资周期
        SalarySobCycleDTO salarySobCycleDTO = getSalarySobService(user).getSalarySobCycle(salaryAcctRecordPO.getSalarySobId(), SalaryDateUtil.localDate2YearMonth(salaryAcctRecordPO.getSalaryMonth()));
        //获取核算的扣缴义务人
        SalarySobPO salarySobPO = getSalarySobService(user).getById(salaryAcctRecordPO.getSalarySobId());
        if (Objects.isNull(salarySobPO)) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98769, "薪资账套不存在或已被删除"));
        }
        List<Long> taxAgentIds = salarySobPO.getTaxAgentIds();

        List<DataCollectionEmployee> employees = getSalaryEmployeeService(user).getEmployeeByIdsAll((List) saveParam.getEmployeeIds());

        // 查询薪资档案
        List<SalaryArchiveDataDTO> salaryArchiveDataDTOS = getSalaryArchiveService(user).getSalaryArchiveTaxAgentData(salarySobCycleDTO.getSalaryCycle(), saveParam.getEmployeeIds(), taxAgentIds);
        // 转换成薪资核算人员po
        List<SalaryAcctEmployeePO> salaryAcctEmployeePOS = SalaryAcctEmployeeBO.convert2Employee(employees, salaryAcctRecordPO, salaryArchiveDataDTOS, (long) user.getUID());


        //过滤不是扣缴义务人下的人员
        salaryAcctEmployeePOS = salaryAcctEmployeePOS.stream().filter(ps -> taxAgentIds.contains(ps.getTaxAgentId())).collect(Collectors.toList());
        // 保存薪资核算人员
        if (CollectionUtils.isEmpty(salaryAcctEmployeePOS)) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98769, "个税扣缴义务人下无该人员档案信息或薪资缴纳日期不在薪资周期内"));
        }

        //保存核算人员
        saveAcctEmployeePOS(salaryAcctEmployeePOS, salarySobCycleDTO);


        // 记录日志
        String targetName = salarySobPO.getName() + ":" + SalaryDateUtil.localDate2YearMonth(salaryAcctRecordPO.getSalaryMonth());
        LoggerContext loggerContext = new LoggerContext<>();
        loggerContext.setUser(user);
        loggerContext.setTargetId("" + salaryAcctRecordPO.getId());
        loggerContext.setTargetName(targetName);
        loggerContext.setOperateType(OperateTypeEnum.ADD.getValue());
        loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel(0, "添加薪资核算人员"));
        loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel(0, "添加薪资核算人员") + ":" + targetName);
        loggerContext.setNewValueList(salaryAcctEmployeePOS);
        SalaryElogConfig.salaryAcctRecordLoggerTemplate.write(loggerContext);
    }

    private void saveAcctEmployeePOS(List<SalaryAcctEmployeePO> salaryAcctEmployeePOS, SalarySobCycleDTO sobCycle) {

        boolean shotEmpBtn = "1".equals(getSalarySysConfService(user).getValueByCode(SalarySysConstant.SHOT_EMP_BTN));

        //替换快照数据
        if (shotEmpBtn) {
//            String valueByCode = getSalarySysConfService(user).getValueByCode(SalarySysConstant.SHOT_EMP_TIME_TYPE);
            shotEmpData(salaryAcctEmployeePOS, sobCycle.getSalaryCycleFromDate());
        }
        //保存
        batchSave(salaryAcctEmployeePOS);
    }

    private void shotEmpData(List<SalaryAcctEmployeePO> salaryAcctEmployeePOS, Date shotTime) {
        List<Long> employees = SalaryEntityUtil.properties(salaryAcctEmployeePOS, SalaryAcctEmployeePO::getEmployeeId, Collectors.toList());
        List<DataCollectionEmployee> snapshot = getSalaryEmployeeService(user).snapshot(employees, shotTime);
        Map<Long, DataCollectionEmployee> shotEmpMap = SalaryEntityUtil.convert2Map(snapshot, DataCollectionEmployee::getEmployeeId);
        salaryAcctEmployeePOS.forEach(salaryAcctEmployeePO -> {
            DataCollectionEmployee shotEmp = shotEmpMap.getOrDefault(salaryAcctEmployeePO.getEmployeeId(), new DataCollectionEmployee());
            salaryAcctEmployeePO.setDepartmentId(shotEmp.getDepartmentId());
            salaryAcctEmployeePO.setDepartmentName(shotEmp.getDepartmentName());
            salaryAcctEmployeePO.setJobcall(shotEmp.getJobcall());
            salaryAcctEmployeePO.setJobcallId(shotEmp.getJobcallId());
            salaryAcctEmployeePO.setJobtitleId(shotEmp.getJobtitleId());
            salaryAcctEmployeePO.setJobtitleName(shotEmp.getJobtitleName());
            salaryAcctEmployeePO.setSubcompanyId(shotEmp.getSubcompanyid());
            salaryAcctEmployeePO.setSubcompanyName(shotEmp.getSubcompanyName());
            salaryAcctEmployeePO.setStatus(shotEmp.getStatus());
            salaryAcctEmployeePO.setAccountType(shotEmp.getAccountType());
        });
    }

    @Override
    public void batchSave(Collection<SalaryAcctEmployeePO> salaryAcctEmployeePOS) {
        if (CollectionUtils.isEmpty(salaryAcctEmployeePOS)) {
            return;
        }
        List<List<SalaryAcctEmployeePO>> partition = Lists.partition((List) salaryAcctEmployeePOS, 50);
        partition.forEach(getSalaryAcctEmployeeMapper()::batchInsert);
    }

    @Override
    public void deleteByIds(Collection<Long> ids) {

        if (CollectionUtils.isEmpty(ids)) {
            return;
        }

        // 删除薪资核算人员
        getSalaryAcctEmployeeMapper().deleteByIds(ids);
        // 删除薪资核算人员对应的薪资核算结果
        getSalaryAcctResultService(user).deleteBySalaryAcctEmployeeIds(ids);
        // 删除报表
        getSalaryAcctReportService(user).deleteBySalaryAcctEmpIds(ids);

        // 删除薪资核算人员对应的校验异常明细
//        salaryCheckResultDetailService.deleteBySalaryAcctEmployeeIds(ids);
        // 删除薪资核算人员对应的线下对比结果
//        salaryComparisonResultService.deleteBySalaryAcctRecordIds(ids);
    }

    @Override
    public void deleteByParam(SalaryAcctEmployeeDeleteParam deleteParam) {
        ValidUtil.doValidator(deleteParam);
        // 查询薪资核算记录
        SalaryAcctRecordPO salaryAcctRecordPO = getSalaryAcctRecordService(user).getById(deleteParam.getSalaryAcctRecordId());
        if (Objects.isNull(salaryAcctRecordPO)) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98747, "薪资核算记录不存在或已被删除"));
        }
        // 回算不允许删除薪资核算人员
        if (Objects.equals(salaryAcctRecordPO.getBackCalcStatus(), 1)) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(0, "正常薪资已经发放，薪资回算时，不允许再删除薪资核算人员"));
        }
        // 只有未归档时才能删除薪资核算人员
        if (!Objects.equals(salaryAcctRecordPO.getStatus(), SalaryAcctRecordStatusEnum.NOT_ARCHIVED.getValue())) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98830, "薪资核算已归档或已申报，不允许再删除薪资核算人员"));
        }
        // 查询薪资核算人员
        List<SalaryAcctEmployeePO> salaryAcctEmployeePOS = listBySalaryAcctRecordIdAndIds(deleteParam.getSalaryAcctRecordId(), deleteParam.getIds());
        if (CollectionUtils.isEmpty(salaryAcctEmployeePOS)) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98830, "薪资核算人员不存在或已被删除"));
        }
        // 删除薪资核算人员
        Set<Long> ids = SalaryEntityUtil.properties(salaryAcctEmployeePOS, SalaryAcctEmployeePO::getId);
        deleteByIds(ids);

        // 查询薪资账套（记录日志用）
        SalarySobPO salarySobPO = getSalarySobService(user).getById(salaryAcctRecordPO.getSalarySobId());
        if (Objects.isNull(salarySobPO)) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98769, "薪资账套不存在或已被删除"));
        }
        // 记录日志
        String targetName = salarySobPO.getName() + ":" + SalaryDateUtil.localDate2YearMonth(salaryAcctRecordPO.getSalaryMonth());
        LoggerContext loggerContext = new LoggerContext<>();
        loggerContext.setUser(user);
        loggerContext.setTargetId("" + salaryAcctRecordPO.getId());
        loggerContext.setTargetName(targetName);
        loggerContext.setOperateType(OperateTypeEnum.DELETE.getValue());
        loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel(0, "删除薪资核算人员"));
        loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel(0, "删除薪资核算人员") + ":" + targetName);
        loggerContext.setOldValueList(salaryAcctEmployeePOS);
        SalaryElogConfig.salaryAcctRecordLoggerTemplate.write(loggerContext);
    }

    @Override
    public void deleteBySalaryAcctRecordIds(Collection<Long> salaryAcctRecordIds) {
        getSalaryAcctEmployeeMapper().deleteBySalaryAcctRecordIds(salaryAcctRecordIds);
    }

    @Override
    public void initBySalaryAcctRecord(SalaryAcctRecordPO salaryAcctRecordPO) {
        // 根据薪资账套查询人员
        List<DataCollectionEmployee> salaryEmployees = getSalaryEmployeeService(user).listBySalarySobId(salaryAcctRecordPO.getSalarySobId(), true);
        if (CollectionUtils.isEmpty(salaryEmployees)) {
            return;
        }
        // 根据薪资账套查询薪资周期
        SalarySobCycleDTO salarySobCycleDTO = getSalarySobService(user).getSalarySobCycle(salaryAcctRecordPO.getSalarySobId(), SalaryDateUtil.localDate2YearMonth(salaryAcctRecordPO.getSalaryMonth()));

//        // 根据薪资账套的"核算人员范围"过滤入职日期大于薪资周期止的人员
//        salaryEmployees = salaryEmployees.stream().filter(salaryEmployee -> StringUtils.isBlank(salaryEmployee.getCompanystartdate()) || (SalaryDateUtil.stringToDate(salaryEmployee.getCompanystartdate()) != null && SalaryDateUtil.stringToDate(salaryEmployee.getCompanystartdate()).compareTo(salarySobCycleDTO.getSalaryCycle().getEndDate()) <= 0)).collect(Collectors.toList());
//
//
//        // 根据薪资账套的"核算人员范围"过滤离职日期小于薪资周期起的人员
//        salaryEmployees = salaryEmployees.stream().filter(salaryEmployee -> StringUtils.isBlank(salaryEmployee.getDismissdate()) || (SalaryDateUtil.stringToDate(salaryEmployee.getCompanystartdate()) != null && SalaryDateUtil.stringToDate(salaryEmployee.getDismissdate()).compareTo(salarySobCycleDTO.getSalaryCycle().getEndDate()) > 0)).collect(Collectors.toList());


        //查询账套对应的扣缴义务人
        SalarySobPO salarySobPO = getSalarySobService(user).getById(salaryAcctRecordPO.getSalarySobId());
        List<Long> taxAgentIds = salarySobPO.getTaxAgentIds();

        // 查询薪资档案，获取人员的个税扣缴义务人
        List<Long> employeeIds = SalaryEntityUtil.properties(salaryEmployees, DataCollectionEmployee::getEmployeeId, Collectors.toList());
        List<SalaryArchiveDataDTO> salaryArchiveDataDTOS = getSalaryArchiveService(user).getSalaryArchiveTaxAgentData(salarySobCycleDTO.getSalaryCycle(), employeeIds, taxAgentIds);
        // 转换成薪资核算人员po
        List<SalaryAcctEmployeePO> salaryAcctEmployeePOS = SalaryAcctEmployeeBO.convert2Employee(salaryEmployees, salaryAcctRecordPO, salaryArchiveDataDTOS, (long) user.getUID());

        //过滤掉不属于当前账套扣缴义务人的人员
        salaryAcctEmployeePOS = salaryAcctEmployeePOS.stream().filter(po -> taxAgentIds.contains(po.getTaxAgentId())).collect(Collectors.toList());

        // 保存薪资核算人员
        if (CollectionUtils.isNotEmpty(salaryAcctEmployeePOS)) {
            saveAcctEmployeePOS(salaryAcctEmployeePOS, salarySobCycleDTO);
        }
    }

    @Override
    public void refresh(Long salaryAcctRecordId) {
        // 查询薪资核算记录
        SalaryAcctRecordPO salaryAcctRecordPO = getSalaryAcctRecordService(user).getById(salaryAcctRecordId);
        if (Objects.isNull(salaryAcctRecordPO)) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98747, "薪资核算记录不存在或已被删除"));
        }

        // 根据薪资账套查询人员
        List<DataCollectionEmployee> salaryEmployees = getSalaryEmployeeService(user).listBySalarySobId(salaryAcctRecordPO.getSalarySobId(), true);
        if (CollectionUtils.isEmpty(salaryEmployees)) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98747, "未查询到账套下关联人员"));
        }

        // 根据薪资账套查询薪资周期
        SalarySobCycleDTO salarySobCycleDTO = getSalarySobService(user).getSalarySobCycle(salaryAcctRecordPO.getSalarySobId(), SalaryDateUtil.localDate2YearMonth(salaryAcctRecordPO.getSalaryMonth()));

        //查询账套对应的扣缴义务人
        SalarySobPO salarySobPO = getSalarySobService(user).getById(salaryAcctRecordPO.getSalarySobId());
        List<Long> taxAgentIds = salarySobPO.getTaxAgentIds();

        // 查询薪资档案，获取人员的个税扣缴义务人
        List<Long> employeeIds = SalaryEntityUtil.properties(salaryEmployees, DataCollectionEmployee::getEmployeeId, Collectors.toList());
        List<SalaryArchiveDataDTO> salaryArchiveDataDTOS = getSalaryArchiveService(user).getSalaryArchiveTaxAgentData(salarySobCycleDTO.getSalaryCycle(), employeeIds, taxAgentIds);

        // 转换成薪资核算人员po
        List<SalaryAcctEmployeePO> newEmps = SalaryAcctEmployeeBO.convert2Employee(salaryEmployees, salaryAcctRecordPO, salaryArchiveDataDTOS, (long) user.getUID());
        //过滤掉不属于当前账套扣缴义务人的人员
        newEmps = newEmps.stream().filter(po -> taxAgentIds.contains(po.getTaxAgentId())).collect(Collectors.toList());
        Map<String, SalaryAcctEmployeePO> newEmpMap = SalaryEntityUtil.convert2Map(newEmps, e -> e.getTaxAgentId() + "_" + e.getEmployeeId());


        // 查询薪资核算人员
        List<SalaryAcctEmployeePO> oldEmps = listBySalaryAcctRecordId(salaryAcctRecordId);
        Map<String, SalaryAcctEmployeePO> oldEmpMap = SalaryEntityUtil.convert2Map(oldEmps, e -> e.getTaxAgentId() + "_" + e.getEmployeeId());

        //新增
        List<SalaryAcctEmployeePO> addEmps = newEmps.stream().filter(po -> !oldEmpMap.containsKey(po.getTaxAgentId() + "_" + po.getEmployeeId())).collect(Collectors.toList());

        //删除
        List<Long> delIds = oldEmps.stream().filter(po -> !newEmpMap.containsKey(po.getTaxAgentId() + "_" + po.getEmployeeId())).map(SalaryAcctEmployeePO::getId).collect(Collectors.toList());

        deleteByIds(delIds);

        saveAcctEmployeePOS(addEmps, salarySobCycleDTO);
    }


    @Override
    public List<SalaryAcctEmployeePO> listBySalaryStatisticsReportParam(SalaryStatisticsReportDataQueryParam param) {
        //排序配置
        OrderRuleVO orderRule = getSalarySysConfService(user).orderRule();
        SalaryAcctEmployeeQueryParam lambdaQueryChainWrapper = new SalaryAcctEmployeeQueryParam();
        lambdaQueryChainWrapper.setOrderRule(orderRule);

        // 个税扣缴义务人
//        Collection<TaxAgentPO> taxAgentList = getTaxAgentService(user).listAllTaxAgents((long) user.getUID());
//        if (CollectionUtils.isNotEmpty(taxAgentList)) {
//            List<Long> taxAgentIds = taxAgentList.stream().map(TaxAgentPO::getId).collect(Collectors.toList());
//            // 有查询参数就取交集
//            if (CollectionUtils.isNotEmpty(param.getTaxAgent())) {
//                List<Long> finalTaxAgentIds = taxAgentIds;
//                taxAgentIds = param.getTaxAgent().stream().filter(finalTaxAgentIds::contains).collect(Collectors.toList());
//                lambdaQueryChainWrapper.setTaxAgentIds(CollectionUtils.isEmpty(taxAgentIds) ? Collections.singletonList(0L) : taxAgentIds);
//            } else {
//                lambdaQueryChainWrapper.setTaxAgentIds(taxAgentIds);
//            }
//        } else {
//            lambdaQueryChainWrapper.setTaxAgentIds(Collections.singletonList(0L));
//        }

        if (CollectionUtils.isNotEmpty(param.getTaxAgent())) {
            lambdaQueryChainWrapper.setTaxAgentIds(param.getTaxAgent());
        } else {
            TaxAgentQueryParam taxAgentQueryParam = TaxAgentQueryParam.builder().build();
            taxAgentQueryParam.setFilterType(AuthFilterTypeEnum.QUERY_DATA);
            Collection<TaxAgentPO> taxAgentPOS = getTaxAgentService(user).listAuth(taxAgentQueryParam);
            List<Long> canManageTaxAgentIds = taxAgentPOS.stream().map(TaxAgentPO::getId).collect(Collectors.toList());
            // 分权
            if (CollectionUtils.isEmpty(canManageTaxAgentIds)) {
                // 无权限
                return Collections.emptyList();
            }
            lambdaQueryChainWrapper.setTaxAgentIds(canManageTaxAgentIds);
        }

        if (CollectionUtils.isNotEmpty(param.getSalarySob())) {
            lambdaQueryChainWrapper.setSalarySobIds(param.getSalarySob());
        } else  {
            // 分权
            SalarySobQueryParam salarySobQueryParam = new SalarySobQueryParam();
            salarySobQueryParam.setFilterType(AuthFilterTypeEnum.QUERY_DATA);
            List<SalarySobPO> salarySobPOS = getSalarySobService(user).listAuth(salarySobQueryParam);
            if (CollectionUtils.isEmpty(salarySobPOS)) {
                // 无权限
                return Collections.emptyList();
            }
            lambdaQueryChainWrapper.setSalarySobIds(salarySobPOS.stream().map(SalarySobPO::getId).collect(Collectors.toList()));
        }

        // 薪资所属月
        Date startYearMonth = SalaryDateUtil.dateStrToLocalYearMonth(param.getSalaryStartMonth());
        Date endYearMonth = SalaryDateUtil.dateStrToLocalYearMonth(param.getSalaryEndMonth());
        if (Objects.nonNull(startYearMonth) && Objects.nonNull(endYearMonth)) {
            Set<Date> yearMonths = Sets.newHashSet();
            while (!startYearMonth.after(endYearMonth)) {
                yearMonths.add(startYearMonth);
                startYearMonth = DateUtil.offsetMonth(startYearMonth, 1);
            }
            lambdaQueryChainWrapper.setSalaryMonths(yearMonths);
        }

        //排除未归档数据
        List<SalaryAcctRecordPO> salaryAcctRecordPOS = getSalaryAcctRecordService(user).listAll();
        List<Long> salaryAcctRecordIds = salaryAcctRecordPOS.stream()
                .filter(po -> !Objects.equals(po.getStatus(), SalaryAcctRecordStatusEnum.NOT_ARCHIVED.getValue()))
                .map(SalaryAcctRecordPO::getId)
                .collect(Collectors.toList());

        List<SalaryAcctEmployeePO> list = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(salaryAcctRecordIds)) {
            //分片查询
            List<List<Long>> partition = Lists.partition(salaryAcctRecordIds, 500);
            for (List<Long> part : partition) {
                lambdaQueryChainWrapper.setSalaryAcctRecordIds(part);
                List<SalaryAcctEmployeePO> pos = getSalaryAcctEmployeeMapper().list(lambdaQueryChainWrapper);
                list.addAll(pos);
            }
        }

        if (CollectionUtils.isEmpty(list)) {
            return Lists.newArrayList();
        }
        List<Long> employeeIds = list.stream().map(SalaryAcctEmployeePO::getEmployeeId).collect(Collectors.toList());


        List<DataCollectionEmployee> employeeList = getSalaryEmployeeService(user).listByIds(employeeIds);
        // 获取分部信息
        List<Long> subCompanyIds = param.getSubCompany();
        if (CollectionUtils.isNotEmpty(subCompanyIds)) {
            if (isRealOrg) {
                employeeList = employeeList.stream().filter(emp -> subCompanyIds.contains(emp.getSubcompanyid())).collect(Collectors.toList());
            } else {
                list = list.stream().filter(emp -> subCompanyIds.contains(emp.getSubcompanyId())).collect(Collectors.toList());
            }
        }

        // 部门过滤
        List<Long> depart = param.getDepart();
        if (CollectionUtils.isNotEmpty(depart)) {
            if (isRealOrg) {
                employeeList = employeeList.stream().filter(emp -> depart.contains(emp.getDepartmentId())).collect(Collectors.toList());
            } else {
                list = list.stream().filter(emp -> depart.contains(emp.getDepartmentId())).collect(Collectors.toList());
            }
        }
        // 岗位过滤
        List<Long> position = param.getPosition();
        if (CollectionUtils.isNotEmpty(position)) {
            if (isRealOrg) {
                employeeList = employeeList.stream().filter(emp -> position.contains(emp.getJobtitleId())).collect(Collectors.toList());
            } else {
                list = list.stream().filter(emp -> position.contains(emp.getJobtitleId())).collect(Collectors.toList());
            }
        }
        // 人事状态过滤
        if (CollectionUtils.isNotEmpty(param.getStatus())) {
            if (isRealOrg) {
                Set<Long> employeeIdsByStatus = new HashSet<>();
                employeeList.forEach(simpleEmployee -> {
                    if (simpleEmployee.getStatus() != null && param.getStatus().contains(simpleEmployee.getStatus())) {
                        employeeIdsByStatus.add(simpleEmployee.getEmployeeId());
                    }
                });
                if (CollectionUtils.isEmpty(employeeIdsByStatus)) {
                    return Lists.newArrayList();
                }
                list = list.stream().filter(po -> employeeIdsByStatus.contains(po.getEmployeeId())).collect(Collectors.toList());
            } else {
                list = list.stream().filter(po -> po.getStatus() != null && param.getStatus().contains(po.getStatus())).collect(Collectors.toList());
            }
        }
        // 入职日期
        if (CollectionUtils.isNotEmpty(param.getHiredate())) {
            Set<Long> employeeIdsByHiredate = new HashSet<>();
            employeeList.forEach(simpleEmployee -> {
                Date hiredate = SalaryDateUtil.stringToDate(simpleEmployee.getCompanystartdate());
                if (hiredate != null && !hiredate.before(param.getHiredate().get(0)) && !hiredate.after(param.getHiredate().get(1))) {
                    employeeIdsByHiredate.add(simpleEmployee.getEmployeeId());
                }
            });
            if (CollectionUtils.isEmpty(employeeIdsByHiredate)) {
                return Lists.newArrayList();
            }
            list = list.stream().filter(po -> employeeIdsByHiredate.contains(po.getEmployeeId())).collect(Collectors.toList());
        }
        // 人员
        if (CollectionUtils.isNotEmpty(param.getEmployee())) {
            list = list.stream().filter(po -> param.getEmployee().contains(po.getEmployeeId())).collect(Collectors.toList());
        }

        if (isRealOrg) {
            Set<Long> empIds = SalaryEntityUtil.properties(employeeList, DataCollectionEmployee::getEmployeeId);
            list = list.stream().filter(po -> empIds.contains(po.getEmployeeId())).collect(Collectors.toList());
        }

        return list;
    }

    @Override
    public List<SalaryAcctEmployeePO> listByTaxAgentAndSalaryMonth(List<Long> taxAgentIds, Set<Date> salaryMonths) {
        return getSalaryAcctEmployeeMapper().listSome(SalaryAcctEmployeePO.builder().taxAgentIds(taxAgentIds).salaryMonths(salaryMonths).build());
    }

    @Override
    public List<SalaryAcctEmployeePO> listBySobAndSalaryMonth(List<Long> salarySobIds, Set<Date> salaryMonths) {
        return getSalaryAcctEmployeeMapper().listSome(SalaryAcctEmployeePO.builder().salarySobIds(salarySobIds).salaryMonths(salaryMonths).build());
    }

    @Override
    public void lockEmp(SalaryAcctResultUpdateLockStatusParam updateParam) {
        List<SalaryAcctEmployeePO> salaryAcctEmployees = listByIds(updateParam.getAcctEmpIds());
        if (CollectionUtils.isEmpty(salaryAcctEmployees)) {
            return;
        }

        LockStatusEnum lockStatus = updateParam.getLockStatus();
        if (lockStatus == null) {
            throw new SalaryRunTimeException("锁定状态异常！");
        }

        if (updateParam.getLockStatus() == LockStatusEnum.LOCK) {
            SalaryAcctConfig salaryAcctSobConfig = getSalaryAcctSobConfigService(user).getSalaryAcctConfig(updateParam.getSalaryAcctRecordId());
            List<SalarySobItemPO> salarySobItems = salaryAcctSobConfig.getSalarySobItems();
            List<Long> itemIds = SalaryEntityUtil.properties(salarySobItems, SalarySobItemPO::getSalaryItemId, Collectors.toList());

            salaryAcctEmployees.forEach(salaryAcctEmployeePO -> {
                salaryAcctEmployeePO.setLockItems(itemIds);
                lock(salaryAcctEmployeePO);
            });
        } else {
            salaryAcctEmployees.forEach(salaryAcctEmployeePO -> {
                salaryAcctEmployeePO.setLockItems(new ArrayList<>());
                lock(salaryAcctEmployeePO);
            });
        }
    }

    @Override
    public void updateIgnoreNull(SalaryAcctEmployeePO salaryAcctEmployeePO) {
        getSalaryAcctEmployeeMapper().updateIgnoreNull(salaryAcctEmployeePO);
    }

    @Override
    public void lock(SalaryAcctEmployeePO salaryAcctEmployeePO) {
        getSalaryAcctEmployeeMapper().lock(salaryAcctEmployeePO);
    }
}
